package com.wf.smartcomm.server.serviceImpl;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.wf.smartcomm.server.bean.House;
import com.wf.smartcomm.server.bean.UnitMachine;
import com.wf.smartcomm.server.bean.User;
import com.wf.smartcomm.server.bean.Village;
import com.wf.smartcomm.server.model.Page;
import com.wf.smartcomm.server.service.HouseService;
import com.wf.smartcomm.server.util.IdUtils;

/** 
 * @author 38884306@qq.com  
 * @version 创建时间：2015-5-20 下午2:27:36 
 * 
 */
@Service
@Transactional
public class HouseServiceImpl implements HouseService {

	@Resource
	private SessionFactory factory;
	
	@Override
	public void save(House house) {
		house.setObjectId(IdUtils.uuid());
		house.setCreatedAt(String.valueOf(System.currentTimeMillis()));
		house.setUpdateAt(house.getCreatedAt());
		factory.getCurrentSession().persist(house);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void listByUser(User user,Page page) {
		Query query = factory.getCurrentSession().createQuery("from House house where house.user = :user");
		query.setParameter("user", user);
		page.setDataList(query.list());
	}

	@Override
	public void update(House house) {
		house.setUpdateAt(String.valueOf(System.currentTimeMillis()));
		factory.getCurrentSession().update(house);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void listByVillage(Village village,Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from House where village = :village");
		query.setParameter("village", village);
		Long counts = (Long) query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from House where village =:village");
		query.setParameter("village", village);
		query.setMaxResults(page.getPageSize());
		query.setFirstResult(page.getBeginIndex());
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public House getByUmInfo(UnitMachine um, String number) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where objectId in (select hid from t_machine_relation_house where mid = :mid) and number = :number").addEntity(House.class);
		query.setParameter("mid", um.getObjectId());
		query.setParameter("number", number);
		return (House) query.uniqueResult();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void list(Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from House");
		Long counts = (Long)query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from House order by building");
		query.setMaxResults(page.getPageSize());
		query.setFirstResult(page.getBeginIndex());
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void queryByKey(Village village,String key, Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from House where village = :village and (name like :key or number like :key)");
		query.setParameter("village", village);
		query.setParameter("key", key+"%");
		Long counts = (Long)query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from House where village = :village and (name like :key or number like :key)");
		query.setParameter("village", village);
		query.setParameter("key", key+"%");
		if (page.getCurrentPage() != -1) {
			query.setMaxResults(page.getPageSize());
			query.setFirstResult(page.getBeginIndex());
		}
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listByHost(String hostId,Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where uid = :hostId").addEntity(House.class);
		query.setParameter("hostId", hostId);
		List<House> list = query.list();
		page.setTotalCount(list.size());
		page.setDataList(list);
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listByAttach(String attachId,Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where objectId in (select hid from t_user_relation_house where uid = :attachId)").addEntity(House.class);
		query.setParameter("attachId", attachId);
		List<House> list = query.list();
		page.setTotalCount(list.size());
		page.setDataList(list);
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public House getById(String hid) {
		Query query = factory.getCurrentSession().createQuery("from House where objectId =:hid");
		query.setParameter("hid", hid);
		return (House) query.uniqueResult();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listBySelect(Village village, String region,String building,String entrance, Page page) {
		//Query query = factory.getCurrentSession().createQuery("from House where village =:village and region =:region and building =:building and entrance =:entrance order by number");
		/*Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where vid =:vid and region =:region and building =:building and entrance =:entrance order by number");
		query.setParameter("vid", village.getObjectId());
		query.setParameter("region", region);
		query.setParameter("building", building);
		query.setParameter("entrance", entrance);
		page.setDataList(query.list());*/
		Session currentSession = factory.getCurrentSession();
		Criteria criteria = currentSession.createCriteria(House.class);
		criteria.add(Restrictions.eq("village", village)).add(Restrictions.eq("region", region)).add(Restrictions.eq("building", building))
		.add(Restrictions.eq("entrance", entrance));
		page.setDataList(criteria.list());
	}
	
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listAllWithNumber(String vid, String region,String building,String entrance, Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select objectId, number from t_house where vid =:vid and region =:region and building =:building and entrance =:entrance order by number");
		query.setParameter("vid", vid);
		query.setParameter("region", region);
		query.setParameter("building", building);
		query.setParameter("entrance", entrance);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listEntrance(String vid,String region, String building, Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select distinct entrance from t_house where vid = :vid and region =:region and building=:building order by entrance");
		query.setParameter("vid", vid);
		query.setParameter("region", region);
		query.setParameter("building", building);
		page.setDataList(query.list());
	}
	
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listBuilding(String vid,String region,Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select distinct building from t_house where vid = :vid and region =:region order by building");
		query.setParameter("vid", vid);
		query.setParameter("region", region);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listRegion(Village village, Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select distinct region from t_house where vid =:vid");
		query.setParameter("vid", village.getObjectId());
		page.setDataList(query.list());
	}

	@Override
	public void addUser(String hid, String uid) {
		String sql = "insert into t_user_relation_house (uid,hid) values (:uid,:hid)";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("uid", uid);
		query.setParameter("hid", hid);
		query.executeUpdate();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listUnlockHouses(User user, Page page) {
		String sql = "select * from t_house where objectId in (select hid from t_user_relation_house where uid =:uid)";
		Query query = factory.getCurrentSession().createSQLQuery(sql).addEntity(House.class);
		query.setParameter("uid", user.getObjectId());
		page.setDataList(query.list());
	}

	@Override
	public void setReceiver(String hid, String uid) {
		String sql = "update t_house set receiver =:uid where objectId =:hid";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("uid", uid);
		query.setParameter("hid", hid);
		query.executeUpdate();
	}

	@Override
	public List<House> listByVillage(String vid) {
		String sql = "select * from t_house where vid =:vid";
		Query query = factory.getCurrentSession().createSQLQuery(sql).addEntity(House.class);
		query.setParameter("vid", vid);
		return query.list();
	}

	@Override
	public void deleteUser(String hid, String attachId) {
		String sql = "delete from t_user_relation_house where hid =:hid and uid =:uid";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("uid", attachId);
		query.setParameter("hid", hid);
		query.executeUpdate();
	}

	@Override
	public List<House> listToJobSchedule(Village village) {
		Query query = factory.getCurrentSession().createQuery("from House where village =:village");
		query.setParameter("village", village);
		return query.list();
	}

	@Override
	public List<User> listUnlocker(House house) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_user where objectId in (select uid from t_user_relation_house where hid =:hid) order by priority desc").addEntity(User.class);
		query.setParameter("hid", house.getObjectId());
		return query.list();
	}

	@Override
	public House getHouseByInfo(String vid, String region, String building, String entrance, String number) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where vid =:vid and region =:region and building =:building and entrance =:entrance and number =:number limit 1").addEntity(House.class);
		query.setParameter("vid", vid);
		query.setParameter("region", region);
		query.setParameter("building", building);
		query.setParameter("entrance", entrance);
		query.setParameter("number", number);
		return (House) query.uniqueResult();
	}

	@Override
	public List<House> listByUm(UnitMachine um) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_house where objectId in (select hid from t_machine_relation_house where mid =:mid)").addEntity(House.class);
		query.setParameter("mid", um.getObjectId());
		return query.list();
	}
}
